﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Xml;
using System.Xml.Linq;
using PanGu;
using System.Collections.ObjectModel;
using System.Xml.Schema;
using PatientInformationExtract.Dictionary.Models;
using PatientInformationExtract.MainInterface.Views;
using PatientInformationExtract.Dictionary.ViewModels;
using System.Diagnostics;
using PatientInformationExtract.Components;

namespace PatientInformationExtract.Dictionary.Views
{
    /// <summary>
    /// Interaction logic for DictionaryManage.xaml
    /// </summary>
    public partial class DictionaryManage : Window
    {
        #region Parameter
        private XmlDocument _xml;
        private XmlNamespaceManager _xnm;
        private Dictionary<string, XmlNode> _catalogNames;
        public Dictionary<string, XmlNode> CatalogNames { set { this._catalogNames = value; } get { return this._catalogNames; } }
        private Dictionary<string, XmlNode> _wordNames;
        private const string CwordsCount = "Count of words : ";
        private XmlNode _searchCurrentNode;
        private XmlNode _dictionaryNode;
        private string _namespaceURI;
        private bool _isClosed;
        public bool IsClosed { get { return this._isClosed; } }

        public delegate void DictionaryManageClosedHandler();
        public event DictionaryManageClosedHandler DictionaryManageClosedEvent;
        public delegate void DictionaryManageSavedHandler();
        public event DictionaryManageSavedHandler DictionaryManageSavedEvent;
        #endregion

        #region Window Operation

        public DictionaryManage()
        {
            InitializeComponent();

            _isClosed = false;
            _xml = new XmlDocument();
            _xml.Load(PanGu.Setting.PanGuSettings.Config.GetDictionaryPath() + "Dict.xml");

            btnDeleteWord.IsEnabled = false;
            btnAlter.IsEnabled = false;
            chkEnableAlter.IsChecked = false;
            btnAddSynonym.IsEnabled = false;
            lstSearchResult.DisplayMemberPath = "Key";
            lstSearchResult.SelectedValuePath = "Value";
        }

        public void AddNewWordOutside(string word, string english)
        {
            AddDictionaryWord addWord = new AddDictionaryWord(word, english, ref this._catalogNames);
            addWord.AddDictionaryWordEvent += new AddDictionaryWord.AddDictionaryWordHandler(AddWord);
            addWord.ShowDialog();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            this.Title += " " + PanGu.Setting.PanGuSettings.Config.GetDictionaryPath() + @"Dict.xml";
            XmlTextReader tr = new XmlTextReader(PanGu.Setting.PanGuSettings.Config.GetDictionaryPath() + "Dictionary-schema.xsd");
            XmlSchemaSet schema = new XmlSchemaSet();
            schema.Add(null, tr);
            _xml.Schemas = schema;

            try
            {
                _xml.Validate(ErrorHandler);
            }
            catch (Exception ex)
            {
                MessageBox.Show(String.Format(DictionaryErrorMessages.ValidationFailed, System.IO.Path.GetFullPath(@".\Dictionaries\Dict.xml"), ex.Message));
                this.Close();
            }

            _xnm = new XmlNamespaceManager(_xml.NameTable);
            _xnm.AddNamespace("dct", "urn:Dictionary");
            _dictionaryNode = _xml.SelectSingleNode(".//dct:Dictionary", _xnm);
            _catalogNames = new Dictionary<string, XmlNode>();
            _wordNames = new Dictionary<string, XmlNode>();
            _catalogNames.Add(_dictionaryNode.Attributes["Name"].Value, _dictionaryNode);
            _namespaceURI = _dictionaryNode.NamespaceURI;
            ReadXml(_dictionaryNode, ref _catalogNames, ref _wordNames);
            cmbCatalog.ItemsSource = _catalogNames;
            RenewMoveToCatalog();

            lblCount.Text = CwordsCount + _wordNames.Count.ToString();
            cmbCatalog.SelectedIndex = 0;
        }

        private void RenewMoveToCatalog()
        {
            List<MenuItem> itemsMoveToCatalog = new List<MenuItem>();
            foreach (KeyValuePair<string, XmlNode> key in _catalogNames)
            {
                MenuItem mi = new MenuItem();
                mi.Header = key.Key;
                mi.Click += new RoutedEventHandler(menuMoveToCatalog_Click);
                itemsMoveToCatalog.Add(mi);
            }
            DictionaryTree.SetMoveToCatalogMenu(itemsMoveToCatalog);
        }

        private void menuMoveToCatalog_Click(object sender, RoutedEventArgs e)
        {
            XmlNode catalogNode;
            _catalogNames.TryGetValue((sender as MenuItem).Header.ToString(), out catalogNode);
            if (catalogNode != null)
            {
                //Delete the current node
                XmlNode node = (tvDictionary.SelectedItem as DictionaryTree).XmlNode;
                XmlNode parent = node.ParentNode;
                node.ParentNode.RemoveChild(node);
                ChangeDisplay(parent);

                //Add to the selected catalog
                catalogNode.InsertAfter(node, catalogNode.LastChild);
                _searchCurrentNode = node;
                lstSearchResult.ItemsSource = null;
            }
        }

        private void btnSearch_Click(object sender, RoutedEventArgs e)
        {
            Dictionary<string, XmlNode> searchResults = new Dictionary<string, XmlNode>();
            foreach (string key in _wordNames.Keys)
            {
                if (key.Contains(txtSearch.Text))
                {
                    XmlNode node;
                    _wordNames.TryGetValue(key, out node);
                    searchResults.Add(key, node);
                }
            }
            if (searchResults.Count != 0)
            {
                lstSearchResult.ItemsSource = searchResults;
            }
            if (_wordNames.TryGetValue(txtSearch.Text, out _searchCurrentNode))
            {
                ChangeDisplay(_searchCurrentNode.ParentNode);
                EnableWordOperationButton();
            }
            else
            {
                if (!lstSearchResult.HasItems)
                {
                    MessageBox.Show(String.Format(DictionaryErrorMessages.FindNoWord, txtSearch.Text));
                    DisableWordOpertationButton();
                }
            }
            txtSearch.Text = "";
        }

        private void lstSearchResult_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            _searchCurrentNode = lstSearchResult.SelectedValue as XmlNode;
            EnableWordOperationButton();
            ChangeDisplay(_searchCurrentNode.ParentNode);
        }

        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            XmlDocument xml = new XmlDocument();
            xml.Load(PanGu.Setting.PanGuSettings.Config.GetDictionaryPath() + "Dict.xml");
            if (!xml.OuterXml.Equals(_xml.OuterXml))
            {
                if (MessageBox.Show("Do you want to save the change?", "Save", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
                {
                    try
                    {
                        _xml.Validate(ErrorHandler);
                        _xml.Save(PanGu.Setting.PanGuSettings.Config.GetDictionaryPath() + "Dict.xml");
                        if (DictionaryManageSavedEvent != null)
                        {
                            this.DictionaryManageSavedEvent();
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(String.Format(DictionaryErrorMessages.ValidationFailed, "Saving", ex.Message));
                    }
                }
            }
        }

        private void ChangeDisplay(XmlNode catalogNode, XmlNode selectedNode)
        {
            if (cmbCatalog.SelectedIndex != _catalogNames.Keys.ToList<string>().IndexOf(catalogNode.Attributes["Name"].Value))
            {
                cmbCatalog.SelectedIndex = _catalogNames.Keys.ToList<string>().IndexOf(catalogNode.Attributes["Name"].Value);
            }
            tvDictionary.ItemsSource = InitDictionaryItemSource(catalogNode, selectedNode);
        }

        private void ChangeDisplay(XmlNode catalogNode)
        {
            ChangeDisplay(catalogNode, null);
        }

        private void ErrorHandler(object sender, ValidationEventArgs args)
        {
            throw new Exception("Dct.xml Validating failed, error message: " + args.Message);
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            XmlDocument xml = new XmlDocument();
            xml.Load(PanGu.Setting.PanGuSettings.Config.GetDictionaryPath() + "Dict.xml");
            if (!xml.OuterXml.Equals(_xml.OuterXml))
            {
                MessageBoxResult result = MessageBox.Show("Dictionary has modified, do you want to save the change?", "Save", MessageBoxButton.YesNoCancel, MessageBoxImage.Warning);
                if (result == MessageBoxResult.Yes)
                {
                    try
                    {
                        _xml.Validate(ErrorHandler);
                        _xml.Save(PanGu.Setting.PanGuSettings.Config.GetDictionaryPath() + "Dict.xml");
                        if (DictionaryManageSavedEvent != null)
                        {
                            this.DictionaryManageSavedEvent();
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(String.Format(DictionaryErrorMessages.ValidationFailed, "Saving", ex.Message));
                    }
                    if (DictionaryManageClosedEvent != null)
                    {
                        this.DictionaryManageClosedEvent();
                    }
                }
                else if (result == MessageBoxResult.No)
                {
                    if (DictionaryManageClosedEvent != null)
                    {
                        this.DictionaryManageClosedEvent();
                    }
                }
                else if (result == MessageBoxResult.Cancel)
                {
                    e.Cancel = true;
                }
            }
            else
            {
                if (DictionaryManageClosedEvent != null)
                {
                    this.DictionaryManageClosedEvent();
                }
            }
        }

        private void ReadXml(XmlNode node, ref Dictionary<string, XmlNode> catalogNames, ref Dictionary<string, XmlNode> wordNames)
        {
            try
            {
                if (node.ChildNodes.Count != 0)
                {
                    foreach (XmlNode n in node.ChildNodes)
                    {
                        if (n.Name.Equals("Word"))
                        {
                            wordNames.Add(n.Attributes["Name"].Value, n);
                            XmlNode synonymNode = n.SelectSingleNode(".//dct:Synonym", _xnm);
                            if (synonymNode != null)
                            {
                                string[] synonyms = synonymNode.InnerText.Split(new char[] { ',' });
                                foreach (string str in synonyms)
                                {
                                    if (str != "")
                                    {
                                        wordNames.Add(str, n);
                                    }
                                }
                            }
                        }
                        if (n.Name.Equals("Catalog"))
                        {
                            catalogNames.Add(n.Attributes["Name"].Value, n);
                            ReadXml(n, ref catalogNames, ref wordNames);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(String.Format(DictionaryErrorMessages.LoadingFailed, "Dict.xml", ex.Message));
                this.Close();
            }
        }

        #endregion

        #region Dictionary Tree Display

        private void TreeViewItem_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            var treeViewItem = VisualUpwardSearch<TreeViewItem>(e.OriginalSource as DependencyObject) as TreeViewItem;
            if (treeViewItem != null)
            {
                treeViewItem.Focus();
                e.Handled = true;
            }
        }

        private static DependencyObject VisualUpwardSearch<T>(DependencyObject source)
        {
            while (source != null && source.GetType() != typeof(T))
                source = VisualTreeHelper.GetParent(source);
            return source;
        }

        private ObservableCollection<DictionaryTree> InitDictionaryItemSource(XmlNode rootNode, XmlNode selectedNode)
        {
            if (rootNode.Name.Equals("Dictionary"))
            {
                btnUpper.IsEnabled = false;
            }
            else
            {
                btnUpper.IsEnabled = true;
            }
            return DictionaryTree.InitRoot(rootNode, false, selectedNode);
        }

        private ObservableCollection<DictionaryTree> InitDictionaryItemSource(XmlNode rootNode)
        {
            return InitDictionaryItemSource(rootNode, null);
        }

        private void cmbCatalog_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (cmbCatalog.HasItems)
            {
                tvDictionary.ItemsSource = InitDictionaryItemSource((XmlNode)cmbCatalog.SelectedValue);
            }
        }

        private void btnUpper_Click(object sender, RoutedEventArgs e)
        {
            XmlNode parentNode = (tvDictionary.ItemsSource as ObservableCollection<DictionaryTree>)[0].XmlNode.ParentNode;
            if (!parentNode.Name.Equals("#document"))
            {
                cmbCatalog.SelectedIndex = _catalogNames.Keys.ToList<string>().IndexOf(parentNode.Attributes["Name"].Value);
            }
        }

        private void tvDictionary_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            DictionaryTree dt = (DictionaryTree)tvDictionary.SelectedItem;
            if (dt != null)
            {
                if (dt.XmlNode.Name.Equals("Catalog"))
                {
                    ChangeDisplay(dt.XmlNode);
                    btnUpper.IsEnabled = true;
                }
                if (dt.XmlNode.Name.Equals("Word"))
                {
                    _searchCurrentNode = dt.XmlNode;
                    EnableWordOperationButton();
                }
                e.Handled = true;
            }
        }

        #endregion

        #region Dictionary Tree Right Button Funtion

        private void menuAddCatalog_Click(object sender, ExecutedRoutedEventArgs e)
        {
            AddDictionaryCatalog addCatalog = new AddDictionaryCatalog();
            addCatalog.AddDictionaryCatalogEvent += new AddDictionaryCatalog.AddDictionaryCatalogHandler(AddCatalog);
            addCatalog.ShowDialog();
        }

        private void AddCatalog(DictionaryCatalog catalog)
        {
            if (!_catalogNames.ContainsKey(catalog.Name))
            {
                DictionaryTree dt = (DictionaryTree)tvDictionary.SelectedItem;
                XmlElement catalogE = dt.XmlDoc.CreateElement("Catalog", _namespaceURI);
                catalogE.SetAttribute("Name", catalog.Name);
                dt.XmlNode.InsertBefore(catalogE, dt.XmlNode.FirstChild);
                _catalogNames.Add(catalog.Name, catalogE);
                cmbCatalog.ItemsSource = null;
                cmbCatalog.ItemsSource = _catalogNames;
                RenewMoveToCatalog();
                ChangeDisplay(dt.XmlNode);
            }
            else
            {
                MessageBox.Show(String.Format(DictionaryErrorMessages.AlreadyExists, "Catalog", catalog.Name), "Error", MessageBoxButton.OK);
            }
        }

        private void menuAddWord_Click(object sender, ExecutedRoutedEventArgs e)
        {
            AddDictionaryWord addWord = new AddDictionaryWord((tvDictionary.SelectedItem as DictionaryTree).XmlNode.Attributes["Name"].Value, (tvDictionary.SelectedItem as DictionaryTree).XmlNode);
            addWord.AddDictionaryWordEvent += new AddDictionaryWord.AddDictionaryWordHandler(AddWord);
            addWord.ShowDialog();
        }

        private void AddWord(DictionaryWord word, XmlNode catalogNode)
        {
            if (_wordNames.ContainsKey(word.Name))
            {
                MessageBox.Show(String.Format(DictionaryErrorMessages.AlreadyExists, "Word", word.Name), "Error", MessageBoxButton.OK);
                this._wordNames.TryGetValue(word.Name, out this._searchCurrentNode);
                this.chkEnableAlter.IsChecked = true;
                this.chkEnableAlter.IsChecked = false;
                return;
            }
            if (word.Synonyms.Count != 0)
            {
                foreach (string synonym in word.Synonyms)
                {
                    if (_wordNames.ContainsKey(synonym) || synonym.Equals(word.Name))
                    {
                        MessageBox.Show(String.Format(DictionaryErrorMessages.AlreadyExists, "Word", synonym), "Error", MessageBoxButton.OK);
                        this._wordNames.TryGetValue(synonym, out this._searchCurrentNode);
                        this.chkEnableAlter.IsChecked = true;
                        this.chkEnableAlter.IsChecked = false;
                        return;
                    }
                }
            }
            XmlElement wordE = catalogNode.OwnerDocument.CreateElement("Word", _namespaceURI);
            wordE.SetAttribute("Name", word.Name);
            if (!String.IsNullOrEmpty(word.English))
            {
                XmlElement englishE = catalogNode.OwnerDocument.CreateElement("English", _namespaceURI);
                englishE.InnerText = word.English;
                wordE.AppendChild(englishE);
            }
            XmlElement posE = catalogNode.OwnerDocument.CreateElement("POS", _namespaceURI);
            posE.InnerText = word.POS.ToString();
            wordE.AppendChild(posE);
            XmlElement frequencyE = catalogNode.OwnerDocument.CreateElement("Frequency", _namespaceURI);
            frequencyE.InnerText = word.Frequency.ToString();
            wordE.AppendChild(frequencyE);
            if (word.Synonyms.Count != 0)
            {
                XmlElement synonymE = catalogNode.OwnerDocument.CreateElement("Synonym", _namespaceURI);
                synonymE.InnerText = String.Join(",", word.Synonyms);
                wordE.AppendChild(synonymE);
            }
            catalogNode.InsertAfter(wordE, catalogNode.LastChild);
            AddWordNames(word, wordE);
            lblCount.Text = CwordsCount + _wordNames.Count.ToString();
            ChangeDisplay(catalogNode);
            _searchCurrentNode = wordE;
            EnableWordOperationButton();
            lstSearchResult.ItemsSource = null;
        }

        private void menuDelete_Click(object sender, ExecutedRoutedEventArgs e)
        {
            XmlNode node = (tvDictionary.SelectedItem as DictionaryTree).XmlNode;
            if (MessageBox.Show("Do you want to delete " + node.Name + " " + node.Attributes["Name"].Value + "?", "Delete", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
            {
                if (node.Name.Equals("Catalog"))
                {
                    _catalogNames.Remove(node.Attributes["Name"].Value);
                    DeleteCatalogNodeFromWordNames(node);
                    RenewMoveToCatalog();
                }
                if (node.Name.Equals("Word"))
                {
                    DeleteWordNodeFromWordNames(node);
                    lblCount.Text = CwordsCount + _wordNames.Count.ToString();
                    if (node == _searchCurrentNode)
                    {
                        DisableWordOpertationButton();
                    }
                }
                XmlNode parent = node.ParentNode;
                node.ParentNode.RemoveChild(node);
                ChangeDisplay(parent);
                lstSearchResult.ItemsSource = null;
            }
        }

        private void menuRename_Click(object sender, ExecutedRoutedEventArgs e)
        {
            AddDictionaryCatalog renameCatalog = new AddDictionaryCatalog((tvDictionary.SelectedItem as DictionaryTree).XmlNode.Attributes["Name"].Value);
            renameCatalog.AddDictionaryCatalogEvent += new AddDictionaryCatalog.AddDictionaryCatalogHandler(RenameCatalog);
            renameCatalog.ShowDialog();
        }

        private void RenameCatalog(DictionaryCatalog catalog)
        {
            XmlNode node = (tvDictionary.SelectedItem as DictionaryTree).XmlNode;
            _catalogNames.Remove(node.Attributes["Name"].Value);
            if (!_catalogNames.ContainsKey(catalog.Name))
            {
                node.Attributes["Name"].Value = catalog.Name;
            }
            else
            {
                MessageBox.Show(String.Format(DictionaryErrorMessages.AlreadyExists, "Catalog", catalog.Name), "Error", MessageBoxButton.OK);
            }
            _catalogNames.Add(node.Attributes["Name"].Value, node);
            cmbCatalog.ItemsSource = null;
            cmbCatalog.ItemsSource = _catalogNames;
            ChangeDisplay(node.ParentNode);
        }

        #endregion

        #region Word Operation Group Box

        private void chkEnableAlter_Unchecked(object sender, RoutedEventArgs e)
        {
            if (_searchCurrentNode != null)
            {
                txtName.Text = _searchCurrentNode.Attributes["Name"].Value;
                cmbPOS.Text = _searchCurrentNode.SelectSingleNode(".//dct:POS", _xnm).InnerText;
                txtFrequency.Text = _searchCurrentNode.SelectSingleNode(".//dct:Frequency", _xnm).InnerText;
                XmlNode synonymNode = _searchCurrentNode.SelectSingleNode(".//dct:Synonym", _xnm);
                XmlNode englishNode = _searchCurrentNode.SelectSingleNode(".//dct:English", _xnm);
                lvwSynonym.Items.Clear();
                if (synonymNode != null)
                {
                    string[] synonyms = synonymNode.InnerText.Split(new char[] { ',' });
                    foreach (string synonym in synonyms)
                    {
                        if (synonym != "")
                        {
                            SynonymListViewItem item = new SynonymListViewItem() { Text = synonym, IsEnabled = false };
                            item.SynonymListViewItemDeletedEvent += new SynonymListViewItem.SynonymListViewItemDeletedHandler(SynonymListViewItemDelete);
                            lvwSynonym.Items.Add(item);
                        }
                    }
                }
                txtEnglish.Text = "";
                if (englishNode != null)
                {
                    txtEnglish.Text = englishNode.InnerText;
                }
                btnAddSynonym.IsEnabled = false;
                btnAlter.IsEnabled = false;
                btnDeleteWord.IsEnabled = true;
            }
        }

        private void chkEnableAlter_Checked(object sender, RoutedEventArgs e)
        {
            btnAlter.IsEnabled = true;
            btnDeleteWord.IsEnabled = false;
            btnAddSynonym.IsEnabled = true;
            foreach (SynonymListViewItem item in lvwSynonym.Items)
            {
                item.IsEnabled = true;
            }
        }

        private void DeleteWordNodeFromWordNames(XmlNode wordNode)
        {
            if (wordNode.Name.Equals("Word"))
            {
                _wordNames.Remove(wordNode.Attributes["Name"].Value);
                XmlNode synonymNode = wordNode.SelectSingleNode(".//dct:Synonym", _xnm);
                if (synonymNode != null)
                {
                    foreach (string synonym in synonymNode.InnerText.Split(new char[] { ',' }))
                    {
                        _wordNames.Remove(synonym);
                    }
                }
            }
            else
            {
                throw new Exception("The deleting node is not a word node.");
            }
        }

        private void DeleteCatalogNodeFromWordNames(XmlNode catalogNode)
        {
            if (catalogNode.Name.Equals("Catalog"))
            {
                foreach (XmlNode wordNode in catalogNode.ChildNodes)
                {
                    DeleteWordNodeFromWordNames(wordNode);
                }
            }
            else
            {
                throw new Exception("The deleting node is not a catalog node.");
            }
        }

        private void AddWordNames(DictionaryWord word, XmlElement wordNode)
        {
            _wordNames.Add(word.Name, wordNode);
            foreach (string synonym in word.Synonyms)
            {
                _wordNames.Add(synonym, wordNode);
            }
        }

        private void AddWordNames(string wordName, List<string> synonyms, XmlNode wordNode)
        {
            _wordNames.Add(wordName, wordNode);
            foreach (string synonym in synonyms)
            {
                _wordNames.Add(synonym, wordNode);
            }
        }

        private void AddWordNames(XmlNode wordNode)
        {
            _wordNames.Add(wordNode.Attributes["Name"].Value, wordNode);
            XmlNode synonymNode = wordNode.SelectSingleNode(".//dct:Synonym", _xnm);
            if (synonymNode != null)
            {
                foreach (string synonym in synonymNode.InnerText.Split(new char[] { ',' }))
                {
                    _wordNames.Add(synonym, wordNode);
                }
            }
        }

        private void EnableWordOperationButton()
        {
            chkEnableAlter.IsEnabled = true;
            if (chkEnableAlter.IsChecked == false)
            {
                chkEnableAlter.IsChecked = true;
            }
            chkEnableAlter.IsChecked = false;
        }

        private void DisableWordOpertationButton()
        {
            btnAlter.IsEnabled = false;
            btnDeleteWord.IsEnabled = false;
            chkEnableAlter.IsEnabled = false;
            chkEnableAlter.IsChecked = false;
            _searchCurrentNode = null;
            txtName.Text = "";
            cmbPOS.Text = "";
            txtFrequency.Text = "";
            txtEnglish.Text = "";
            lvwSynonym.Items.Clear();
        }

        private void SynonymListViewItemDelete(SynonymListViewItem item)
        {
            item.SynonymListViewItemDeletedEvent -= SynonymListViewItemDelete;
            lvwSynonym.Items.Remove(item);
            item = null;
        }

        private void btnDeleteWord_Click(object sender, RoutedEventArgs e)
        {
            if (_searchCurrentNode != null)
            {
                if (MessageBox.Show("Do you want to delete " + _searchCurrentNode.Name + " " + _searchCurrentNode.Attributes["Name"].Value + "?", "Delete", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
                {
                    DeleteWordNodeFromWordNames(_searchCurrentNode);
                    XmlNode parentNode = _searchCurrentNode.ParentNode;
                    parentNode.RemoveChild(_searchCurrentNode);
                    ChangeDisplay(parentNode);
                    lstSearchResult.ItemsSource = null;
                    lblCount.Text = CwordsCount + _wordNames.Count.ToString();
                    DisableWordOpertationButton();
                }
            }
        }

        private void btnAlter_Click(object sender, RoutedEventArgs e)
        {
            if (_searchCurrentNode != null)
            {
                DeleteWordNodeFromWordNames(_searchCurrentNode);
                List<string> synonyms = new List<string>();
                if (_wordNames.Keys.Contains(txtName.Text))
                {
                    MessageBox.Show(String.Format(DictionaryErrorMessages.AlreadyExists, "Word", txtName.Text), "Error", MessageBoxButton.OK);
                    chkEnableAlter.IsChecked = false;
                    AddWordNames(_searchCurrentNode);
                    return;
                }
                foreach (SynonymListViewItem item in lvwSynonym.Items)
                {
                    if (_wordNames.Keys.Contains(item.Text) || synonyms.Contains(item.Text) || item.Text.Equals(txtName.Text))
                    {
                        MessageBox.Show(String.Format(DictionaryErrorMessages.AlreadyExists, "Word", item.Text), "Error", MessageBoxButton.OK);
                        chkEnableAlter.IsChecked = false;
                        AddWordNames(_searchCurrentNode);
                        return;
                    }
                    synonyms.Add(item.Text);
                }
                _searchCurrentNode.Attributes["Name"].Value = txtName.Text;
                _searchCurrentNode.SelectSingleNode(".//dct:POS", _xnm).InnerText = cmbPOS.Text;
                _searchCurrentNode.SelectSingleNode(".//dct:Frequency", _xnm).InnerText = txtFrequency.Text;
                XmlNode synonymNode = _searchCurrentNode.SelectSingleNode(".//dct:Synonym", _xnm);
                XmlNode englishNode = _searchCurrentNode.SelectSingleNode(".//dct:English", _xnm);
                if (synonyms.Count != 0)
                {
                    if (synonymNode == null)
                    {
                        synonymNode = _searchCurrentNode.OwnerDocument.CreateElement("Synonym", _namespaceURI);
                        _searchCurrentNode.AppendChild(synonymNode);
                    }
                    synonymNode.InnerText = String.Join(",", synonyms);
                }
                if (englishNode == null)
                {
                    if (txtEnglish.Text != "")
                    {
                        englishNode = _searchCurrentNode.OwnerDocument.CreateElement("English", _namespaceURI);
                        englishNode.InnerText = txtEnglish.Text;
                        _searchCurrentNode.InsertBefore(englishNode, _searchCurrentNode.SelectSingleNode(".//dct:POS", _xnm));
                    }
                }
                else
                {
                    englishNode.InnerText = txtEnglish.Text;
                }
                AddWordNames(txtName.Text, synonyms, _searchCurrentNode);
                chkEnableAlter.IsChecked = false;
                lstSearchResult.ItemsSource = null;
                ChangeDisplay(_searchCurrentNode.ParentNode);
                MessageBox.Show("Operate succeess.");
            }
        }

        private void btnAdd_Click(object sender, RoutedEventArgs e)
        {
            AddDictionaryWord addWord = new AddDictionaryWord(ref _catalogNames);
            addWord.AddDictionaryWordEvent += new AddDictionaryWord.AddDictionaryWordHandler(AddWord);
            addWord.ShowDialog();
        }

        private void btnAddSynonym_Click(object sender, RoutedEventArgs e)
        {
            SynonymListViewItem item = new SynonymListViewItem() { IsEnabled = true };
            item.SynonymListViewItemDeletedEvent += new SynonymListViewItem.SynonymListViewItemDeletedHandler(SynonymListViewItemDelete);
            lvwSynonym.Items.Add(item);
        }

        #endregion

        private void Window_Closed(object sender, EventArgs e)
        {
            this._isClosed = true;
        }

        private void btnMoveDown_Click(object sender, RoutedEventArgs e)
        {
            DictionaryTree dt = tvDictionary.SelectedItem as DictionaryTree;
            if (dt != null & dt.Parent != null)
            {
                XmlNode nextNode = dt.XmlNode.NextSibling;
                dt.Parent.XmlNode.RemoveChild(dt.XmlNode);
                dt.Parent.XmlNode.InsertAfter(dt.XmlNode, nextNode);
                ChangeDisplay(dt.Parent.XmlNode, dt.XmlNode);
            }
        }

        private void btnMoveUp_Click(object sender, RoutedEventArgs e)
        {
            DictionaryTree dt = tvDictionary.SelectedItem as DictionaryTree;
            if (dt != null & dt.Parent != null)
            {
                XmlNode previousNode = dt.XmlNode.PreviousSibling;
                dt.Parent.XmlNode.RemoveChild(dt.XmlNode);
                dt.Parent.XmlNode.InsertBefore(dt.XmlNode, previousNode);
                ChangeDisplay(dt.Parent.XmlNode, dt.XmlNode);
            }
        }

        private void txtSearch_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key.Equals(Key.Enter))
            {
                btnSearch.RaiseEvent(new RoutedEventArgs(Button.ClickEvent, this));
            }
        }
    }
}
